<script setup lang="ts">
defineOptions({
  name: "previewSpec"
});

import { ref, onMounted, defineAsyncComponent } from "vue";
import { useRouter } from "vue-router";
import { queryFabSPECDetail } from "@/api/modules/fab";
import { useRouterStoreHook } from "@/store/modules/router";
import dayjs from "dayjs";

const echartsCom = defineAsyncComponent(() => import("@/views/common/components/echartsCom/index.vue"));

const router = useRouter();
const routerStore = useRouterStoreHook();
const echartsComRef = ref<InstanceType<typeof echartsCom> | null>(null);
const echartsOptions = ref<CommonEcharts.CommonEchartsOption | null>(null);
const dialogTableVisible = defineModel({ type: Boolean, default: false });

interface ActualDataType {
  name?: string;
  data?: Array<any>;
  xAxisData?: Array<any>;
  [key: string]: any;
}

const props = withDefaults(
  defineProps<{
    list?: Array<any>;
    data?: Record<string, any>;
    isEdit?: boolean;
    eqpId?: string;
    quotaSingleCode?: string;
    actualData?: ActualDataType;
  }>(),
  {
    list: () => null,
    data: () => null,
    isEdit: false,
    eqpId: "",
    quotaSingleCode: "",
    actualData: () => ({})
  }
);

const previewSpecData = ref<Record<string, any>>({});
const lineType = ref<"all" | "up" | "down" | "">("all");
const lineTypeOption = ref<Array<any>>([
  {
    label: "双边",
    value: "all",
    disabled: false
  },
  {
    label: "上单边",
    value: "up",
    disabled: false
  },
  {
    label: "下单边",
    value: "down",
    disabled: false
  }
]);
const previewSpecValue = ref<string>("");
const previewSpecOption = ref<Array<any>>([]);

const lineTypeChangeHandler = async (val?: string, flag: boolean = false) => {
  let {
    actualData: { name = "", data = [], xAxisData = [] },
    isEdit = false
  } = props;
  switch (val) {
    case "up":
      isEdit ? initEcharts(["up"]) : initEcharts(["up"], name, data, xAxisData);
      break;
    case "down":
      isEdit ? initEcharts(["down"]) : initEcharts(["down"], name, data, xAxisData);
      break;
    default:
      isEdit ? initEcharts(["up", "down"]) : initEcharts(["up", "down"], name, data, xAxisData);
      break;
  }
  !flag && (await echartsComRef.value?.updateOption(true));
};

const previewSpecChangeHandler = async (val: string) => {
  const res = await queryFabSPECDetail({ quotaSingleCode: previewSpecValue.value });
  previewSpecData.value = res || {};
  const { controlLine = [] } = previewSpecData.value;
  if (controlLine?.length) {
    for (const item of lineTypeOption.value) {
      if (item.value !== "all") {
        item.disabled = !controlLine?.includes(item.value);
      }
    }
    await lineTypeChangeHandler(lineType.value, true);
  } else {
    echartsOptions.value = null;
  }
};

const toSetSpec = () => {
  let quotaSingleCode = previewSpecData.value?.quotaSingleCode;
  if (!quotaSingleCode) {
    quotaSingleCode = previewSpecValue.value;
  }
  if (!quotaSingleCode) {
    quotaSingleCode = props.quotaSingleCode;
  }
  const { eqpId } = props;
  const className = routerStore.getSubject.toLowerCase();
  const path = `/${className}/fab/monitoring/specOverView/setSpec`;
  const query = { quotaSingleCode, eqpId };
  router.push({ path, query });
};

const getSingleSeries = (code: string, val = undefined, specColor = [], xAxisLen = 24, data = []): Record<string, any> => {
  let name = code;
  const type = "line";
  let symbol = "none";
  let showSymbol = false;
  let color = "";
  let itemStyle = null;
  let endLabel = null;
  let lineStyle = null;
  if (data?.length === xAxisLen && !val && !specColor?.length) {
    symbol = "circle";
    showSymbol = true;
    color = "#666";
    itemStyle = {
      color
    };
    endLabel = {
      show: false
    };
    lineStyle = {
      color,
      width: 1
    };
  } else {
    name = name.toUpperCase();
    data = [];
    let num = 0;
    do {
      data.push(val);
      num++;
    } while (num < xAxisLen);
    color = specColor.find(item => item.code === `${code}Color`)?.colorValue || undefined;
    endLabel = {
      show: true,
      color,
      formatter: "{a}: {c}"
    };
    lineStyle = {
      color,
      width: 1,
      type: "dashed"
    };
  }
  return { name, type, symbol, showSymbol, itemStyle, data, endLabel, lineStyle };
};

const getEchartsSeries = (type?: "up" | "down" | "target" | "actual", name?: string, xAxisLen?: number, data?: Array<any>): Array<any> => {
  const {
    uslValue = undefined,
    uclValue = undefined,
    uwlValue = undefined,
    targetValue = undefined,
    lwlValue = undefined,
    lclValue = undefined,
    lslValue = undefined,
    specColor = []
  } = previewSpecData.value;
  const ss = [];
  if (type === "up") {
    if (uslValue) {
      const s = getSingleSeries("usl", uslValue, specColor, xAxisLen, data);
      ss.push(s);
    }
    if (uclValue) {
      const s = getSingleSeries("ucl", uclValue, specColor, xAxisLen, data);
      ss.push(s);
    }
    if (uwlValue) {
      const s = getSingleSeries("uwl", uwlValue, specColor, xAxisLen, data);
      ss.push(s);
    }
  } else if (type === "down") {
    if (lwlValue) {
      const s = getSingleSeries("lwl", lwlValue, specColor, xAxisLen, data);
      ss.push(s);
    }
    if (lclValue) {
      const s = getSingleSeries("lcl", lclValue, specColor, xAxisLen, data);
      ss.push(s);
    }
    if (lslValue) {
      const s = getSingleSeries("lsl", lslValue, specColor, xAxisLen, data);
      ss.push(s);
    }
  } else if (type === "target") {
    const s = getSingleSeries("target", targetValue, specColor, xAxisLen, data);
    ss.push(s);
  } else if (type === "actual") {
    const ac = getSingleSeries(name, undefined, null, xAxisLen, data);
    ss.push(ac);
  }
  return ss;
};

const getDefaultXAxisData = () => {
  const xAxisData = [];
  let num = 0;
  do {
    const t = dayjs().subtract(num, "hour").format("MM/DD HH:mm");
    xAxisData.unshift(t);
    num++;
  } while (num < 24);
  return xAxisData;
};

const initEcharts = (controlLine: Array<string> = [], name?: string, data?: Array<any>, xAxisData?: Array<any>) => {
  if (!previewSpecData.value) return null;
  const {
    startValue: min = undefined,
    step: interval = undefined,
    targetValue = undefined,
    indicatorName = "",
    pointUnit = ""
  } = previewSpecData.value;
  if (!xAxisData?.length) {
    xAxisData = getDefaultXAxisData();
  }
  const animation = false;
  const grid = {
    top: 28,
    bottom: 0,
    left: 32,
    right: 110,
    containLabel: true
  };
  const tooltip = {
    show: name && data?.length && xAxisData?.length
  };
  const xAxis = {
    name: "时间",
    type: "category",
    splitLine: {
      show: true
    },
    axisLabel: {
      rotate: 45
    },
    boundaryGap: false,
    data: xAxisData
  };
  const yAxis = {
    name: `${indicatorName}${pointUnit ? "（" + pointUnit + "）" : ""}`,
    nameTextStyle: {
      align: "left"
    },
    type: "value",
    splitLine: {
      show: true
    },
    min,
    interval
  };
  const series = [];
  if (controlLine?.includes("up")) {
    let s = [];
    if (name && data?.length && xAxisData?.length) {
      s = getEchartsSeries("up", name, data.length, data);
    } else {
      s = getEchartsSeries("up");
    }
    series.push(...s);
  }
  if (controlLine?.includes("down")) {
    let s = [];
    if (name && data?.length && xAxisData?.length) {
      s = getEchartsSeries("down", name, data.length, data);
    } else {
      s = getEchartsSeries("down");
    }
    series.push(...s);
  }

  if (targetValue) {
    let t = [];
    if (name && data?.length && xAxisData?.length) {
      t = getEchartsSeries("target", name, data.length, data);
    } else {
      t = getEchartsSeries("target");
    }
    series.push(...t);
  }

  if (name && data?.length && xAxisData?.length) {
    const ac = getEchartsSeries("actual", name, data.length, data);
    series.push(...ac);
  }
  echartsOptions.value = { animation, grid, tooltip, xAxis, yAxis, series };
};

const init = async () => {
  const { data = null, list = [], actualData = null, isEdit = false } = props;
  if (data) {
    if (isEdit) {
      previewSpecData.value = data;
    } else {
      const { quotaSingleCode } = data;
      const res = await queryFabSPECDetail({ quotaSingleCode });
      if (!res) return;
      previewSpecData.value = res;
    }
  } else if (list?.length) {
    previewSpecOption.value = [...list];
    previewSpecValue.value = list.reduce((pre, cur) => {
      if (!pre && cur.quotaStatus) {
        pre = cur.singleCode;
      }
      return pre;
    }, "");
    const res = await queryFabSPECDetail({ quotaSingleCode: previewSpecValue.value });
    if (!res) return;
    previewSpecData.value = res;
  }
  const { controlLine = [] } = previewSpecData.value;
  for (const item of lineTypeOption.value) {
    if (item.value === "all") {
      item.disabled = controlLine?.length !== 2;
    } else {
      item.disabled = !controlLine?.includes(item.value);
    }
  }
  if (controlLine?.length === 2) {
    lineType.value = "all";
  } else if (controlLine?.length === 1) {
    lineType.value = controlLine[0];
  } else {
    lineType.value = "";
  }
  if (actualData?.name) {
    await lineTypeChangeHandler("", true);
  } else if (controlLine?.length) {
    await lineTypeChangeHandler(lineType.value, true);
  } else {
    echartsOptions.value = null;
  }
};

onMounted(async () => {
  await init();
});
</script>

<template>
  <px-dialog v-model="dialogTableVisible" title="SPEC上下限预览" width="1200px">
    <div class="preview-spec">
      <div v-if="previewSpecOption?.length" class="preview-spec-title">
        <!-- 暂时注释掉 -->
        <!--
        <px-radio-group v-model="lineType" @change="lineTypeChangeHandler">
          <px-radio-button v-for="item in lineTypeOption" :key="item.value" :label="item.value" :disabled="item.disabled">{{
            item.label
          }}</px-radio-button>
        </px-radio-group>
      -->
        <px-select v-if="previewSpecOption?.length" v-model="previewSpecValue" @change="previewSpecChangeHandler">
          <px-option
            v-for="item in previewSpecOption"
            :key="item.singleCode"
            :label="`${item.materialName || ''}-${item.quotaName || ''}`"
            :value="item.singleCode"
            :disabled="!item.quotaStatus"
          />
        </px-select>
      </div>
      <div class="preview-spec-echarts">
        <Suspense>
          <template #fallback>
            <div v-loading="true" class="echarts-fallback" />
          </template>
          <template #default>
            <div class="echarts-default">
              <echartsCom ref="echartsComRef" :options="echartsOptions">
                <template #emptyDefault>
                  <px-button type="primary" text plain @click="toSetSpec">去设定</px-button>
                </template>
              </echartsCom>
            </div>
          </template>
        </Suspense>
      </div>
    </div>
  </px-dialog>
</template>

<style lang="scss" scoped>
.preview-spec {
  .preview-spec-title {
    display: flex;
    align-items: center;
    // justify-content: space-between;
    justify-content: flex-end;
    width: 100%;
    margin-bottom: 16px;
  }

  .preview-spec-echarts {
    width: 100%;

    .echarts-fallback {
      display: flex;
      flex-direction: column;
      gap: 16px;
      align-items: center;
      justify-content: center;
      width: 100%;
      height: 500px;
    }

    .echarts-default {
      width: 100%;
      height: 500px;
    }
  }
}
</style>
